//
//  TCPParseUtil.m
//  TimeBoat
//
//  Created by Jun on 2022/9/9.
//  Copyright © 2022 Time Boat. All rights reserved.
//

#import "TCPCMDUtil.h"
#import "TimeBoat-Swift.h"

// 命令格式：[厂商*设备ID*内容长度*内容]
static NSString *PREFIX = @"[";
static NSString *SUFFIX = @"]";
static NSString *COMMA = @",";
static NSString *SEP = @"*";


@implementation TCPCMDUtil

+ (instancetype)shared {
    static TCPCMDUtil *instance = nil;
    static dispatch_once_t oneToken;
    dispatch_once(&oneToken,^{
        instance = [[TCPCMDUtil alloc] init];
    });
    
    return instance;
}

- (nullable NSString *)buildCommand:(nullable NSString *)header
                               imei:(nullable NSString *)imei
                            cmdType:(nullable NSString *)cmdType
                               data:(nullable NSArray<NSString*> *)data {
    if (NULL != header && NULL != imei && NULL != cmdType) {
        NSString * dataStr = @"";
        if (NULL != data && data.count > 0) {
            dataStr = [data componentsJoinedByString:COMMA];
        }
        
        if (NULL != dataStr && dataStr.length > 0) {
            dataStr = [COMMA stringByAppendingString:dataStr];
        } else {
            dataStr = @"";
        }
        
        int len = (int)cmdType.length + (int)dataStr.length;
        NSString *strLen = [NSString stringWithFormat:@"%04X", len];
        
        return [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@%@", PREFIX, header, SEP, imei, SEP, strLen, SEP, cmdType, dataStr, SUFFIX];
    }
    
    return NULL;
}

- (nullable NSData *)buildHeader:(nullable NSString *)header
                            imei:(nullable NSString *)imei
                         cmdType:(nullable NSString *)cmdType
                            data:(nullable NSArray<NSString*> *)data {
    NSString *cmd = [self buildCommand:header imei:imei cmdType:cmdType data:data];
    
    if (NULL != cmd) {
        return [NSData dataWithBytes:cmd.UTF8String length:cmd.length];
    }
    
    return NULL;
}


- (nullable NSString *)buildCommand:(nullable TCPCMDModel *)model {
    if (NULL != model) {
        return [self buildCommand:model.header
                             imei:model.imei
                          cmdType:model.cmdType
                             data:model.dataList];
    }
    
    return NULL;
}

- (nullable NSData *)buildCommandData:(nullable TCPCMDModel *)model {
    if (NULL != model) {
        NSString *cmd = [self buildCommand:model.header
                                      imei:model.imei
                                   cmdType:model.cmdType
                                      data:model.dataList];
        if (NULL != cmd) {
            return [NSData dataWithBytes:cmd.UTF8String length:cmd.length];
        }
    }
    
    return NULL;
}

- (nullable TCPCMDModel *)buildCommandModel:(nullable NSString *)header
                                       imei:(nullable NSString *)imei
                                    cmdType:(nullable NSString *)cmdType
                                       data:(nullable NSArray<NSString *> *)data {
    if (NULL != header && header.length > 0 && NULL != imei && imei.length > 0 && NULL != cmdType && cmdType.length > 0) {
        TCPCMDModel *model = [[TCPCMDModel alloc] init];
        model.header = header;
        model.imei = imei;
        model.cmdType = cmdType;
        model.dataList = data;
        
        return model;
    }
    
    return NULL;
}

- (nullable NSString *)responseCommand:(nullable NSString *)header
                                  imei:(nullable NSString *)imei
                               cmdType:(nullable NSString *)cmdType {
    if (NULL != header && header.length > 0 && NULL != imei && imei.length > 0 && NULL != cmdType && cmdType.length > 0) {
        int len = (int)cmdType.length;
        NSString *strLen = [NSString stringWithFormat:@"%04X", len];
        
        return [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@", PREFIX, header, SEP, imei, SEP, strLen, SEP, cmdType, SUFFIX];
    }
    
    return NULL;
}

- (nullable NSString *)responseCommand:(nullable TCPCMDModel *)model {
    if (NULL != model) {
        return [self responseCommand:model.header imei:model.imei cmdType:model.cmdType];
    }
    
    return NULL;
}

- (nullable NSData *)responseCommandData:(nullable TCPCMDModel *)model {
    if (NULL != model) {
        NSString *cmd = [self responseCommand:model];
        if (NULL != cmd) {
            return [NSData dataWithBytes:cmd.UTF8String length:cmd.length];
        }
    }
    
    return NULL;
}

- (nullable TCPCMDModel *)responseCommandModel:(nullable NSString *)header
                                          imei:(nullable NSString *)imei
                                       cmdType:(nullable NSString *)cmdType {
    if (NULL != header && NULL != imei && NULL != cmdType) {
        TCPCMDModel *model = [[TCPCMDModel alloc] init];
        model.header = header;
        model.imei = imei;
        model.cmdType = cmdType;
        
        return model;
    }
    
    return NULL;
}

- (nullable TCPCMDModel *)responseCommandModel:(nullable TCPCMDModel *)model {
    if (NULL != model) {
        return [self responseCommandModel:model.header
                                     imei:model.imei
                                  cmdType:model.cmdType];
    }
    
    return NULL;
}

- (nullable NSArray<TCPCMDModel *> *)parseCommand:(nullable NSString *)readCommand {
    NSMutableArray<TCPCMDModel *> *cmdList = [NSMutableArray array];
    
    int prefixIndex = -1;
    int suffixIndex = -1;
    int beginIndex = -1;
    int endIndex = -1;
    NSString *cmd = NULL;
    TCPCMDModel *item = NULL;
    
    if (NULL != readCommand && readCommand.length > 0) {
        NSString *command = readCommand;
        while (true) {
            prefixIndex = (int)[command rangeOfString:PREFIX].location;
            if (prefixIndex < 0) {
                DMLog(@"prefixIndex = %@, command= %@", @(prefixIndex), command);
                break;
            }
            
            suffixIndex = (int)[command rangeOfString:SUFFIX].location;
            if (suffixIndex < 0) {
                DMLog(@"suffixIndex = %@, command= %@", @(suffixIndex), command);
                break;
            }
            
            beginIndex = prefixIndex;
            endIndex = suffixIndex + 1;
            if ((endIndex - beginIndex) <= 0) {
                DMLog(@"beginIndex = %@, endIndex = %@, command= %@", @(beginIndex), @(endIndex), command);
                break;
            }
            
            cmd = [[command substringFromIndex:prefixIndex] substringToIndex:endIndex];//command.substring(prefixIndex, endIndex);
            command = [command substringFromIndex:endIndex];//command.substring(endIndex);
            
            NSString *trimCmd = [[cmd stringByReplacingOccurrencesOfString:PREFIX withString:@""] stringByReplacingOccurrencesOfString:SUFFIX withString:@""];//cmd.replace(PREFIX, "").replace(SUFFIX, "");
            NSArray<NSString *> *cmds = [trimCmd componentsSeparatedByString:COMMA];//trimCmd.split(COMMA);
            
            if (cmds.count > 0) {
                for (int i = 0; i < cmds.count; i++) {
                    NSString *parseStr = cmds[i];
                    if (0 == i) {
                        // command
                        NSArray<NSString *> *items = [parseStr componentsSeparatedByString:[@"\\" stringByAppendingString:SEP]];//parseStr.split("\\" + SEP);
                        if (items.count >= 4) {
                            NSString *checksum = NULL;
                            NSString *header = items[0];
                            NSString *imei = items[1];
                            int len = (int)strtoul([items[2] UTF8String], NULL, 16); //strToInt(items[2], 16);
                            NSString *cmdType = items[3];
                            
                            header = TCPCMDHeaderType.H_SGZ_A;
                            checksum = @"";
                            
                            item = [[TCPCMDModel alloc] init];
                            item.header = header;
                            item.imei = imei;
                            item.len = len;
                            item.cmdType = cmdType;
                            item.dataList = [NSMutableArray array];
                            item.sourceCommand = cmd;
                            item.checksum = checksum;
                            [cmdList addObject:item];
                        } else {
                            break;
                        }
                    } else {
                        if (NULL != item && NULL != item.dataList) {
                            NSMutableArray<NSString *> *array = [[NSMutableArray alloc] initWithArray:item.dataList];
                            [array addObject:parseStr];
                            item.dataList = array;
                        }
                    }
                }
            }
        }
    }
    
    return cmdList;
}

@end
